'''

Case Type： 数据库系统
Case Name： 套接字文件重命名，暂停数据库进程（接收kill -19信号）
Create At:  2020/07/27
@zou_jialiang0505328126
Descption:  1. 获取套接字文件路径2. 获取套接字文件名3. 修改套接字文件名称4. 获取pid5. 停止进程6. 连接数据库7. 恢复进程8. 连接数据库9. 运行tpcc指令10. 恢复socket文件名称11. 连接数据库

history：
created： 2020/07/27  created by @wan005
'''
import os
import unittest
from yat.test import Node
import time
from yat.test import macro
import sys

sys.path.append(sys.path[0] + "/../")
from testcase.utils.Logger import Logger
from testcase.utils.Constant import Constant
from testcase.utils.Common import Common
from testcase.utils.CommonSH import *
from testcase.utils.ComThread import ComThread

logger = Logger()
common = Common()
Constant = Constant()


class StopImmediate(unittest.TestCase):
    dbPrimaryUserNode = Node(node='PrimaryDbUser')
    dbPrimaryRootNode = Node(node='PrimaryRoot')
    DB_INSTANCE_PATH = macro.DB_INSTANCE_PATH
    DB_ENV_PATH = macro.DB_ENV_PATH
    GS_CTL_STOP_SUCCESS_MSG = Constant.GS_CTL_STOP_SUCCESS_MSG
    STANDBY_NORMAL = Constant.STANDBY_NORMAL
    PRIMARY_NORMAL = Constant.PRIMARY_NORMAL
    START_SUCCESS_MSG = Constant.START_SUCCESS_MSG
    TPCC_SUCCESS_MSG = Constant.TPCC_SUCCESS_MSG
    RESTART_SUCCESS_MSG = Constant.RESTART_SUCCESS_MSG
    file_name = ''
    file_name_bak = ''
    TPCC_PATH = macro.TPCC_PATH
    primary_sh = CommonSH('PrimaryDbUser')
    standby_1_sh = CommonSH('Standby1DbUser')
    standby_2_sh = CommonSH('Standby2DbUser')
    nodes_tuple = ('PrimaryDbUser', 'Standby1DbUser', 'Standby2DbUser')

    @RestartDbCluster(*nodes_tuple)
    def setUp(self):
        logger.info("-----------this is setup-----------")
        logger.info('------------Opengauss_Reliability_Dbsys_Case165.py start------------')

    def test_stop_immediate(self):
        time.sleep(30)
        logger.info("----------------------get socket file path--------------")
        sql = "show unix_socket_directory"
        getfilepathMsg = self.primary_sh.executDbSql(sql)
        logger.info(getfilepathMsg)
        file_path = getfilepathMsg.split('\n')[2]
        logger.info(file_path)

        logger.info("----------------------get socket file name--------------")
        get_file_list_cmd = f'ls -a {file_path}'
        logger.info(get_file_list_cmd)
        file_list = self.dbPrimaryUserNode.sh(get_file_list_cmd).result()
        logger.info(file_list)
        socket_file_name = ''
        for file in file_list.split():
            logger.info(file)
            if (self.dbPrimaryUserNode.db_port not in file) or ('lock' in file):
                pass
            else:
                socket_file_name = file
        logger.info(socket_file_name)
        self.file_name = file_path + "/" + socket_file_name
        self.file_name_bak = file_path + "/tmptest"

        logger.info("------------------delete socket file----------------------")
        deleteCmd = f'mv {self.file_name} {self.file_name_bak}'
        logger.info(deleteCmd)
        self.dbPrimaryUserNode.sh(deleteCmd)

        logger.info("-----------------------stop pid-------------------------------")
        msg = common.kill_pid(self.dbPrimaryRootNode, '19')
        self.assertEqual(msg, '')

        logger.info("----------------------connect opengauss----------------------")
        nosocket_connect = ComThread(self.primary_sh.nosocketConnect, args=())
        nosocket_connect.setDaemon(True)
        nosocket_connect.start()

        socket_connect = ComThread(self.primary_sh.socket_connect, args=(file_path,))
        socket_connect.setDaemon(True)
        socket_connect.start()

        nosocket_connect.join(60 * 10)
        no_socket_connect_msg = nosocket_connect.get_result()
        logger.info('no_socket_connect_msg:' + str(no_socket_connect_msg))
        self.assertIn(Constant.TIMEOUT_EXPIRED_MSG, no_socket_connect_msg)

        socket_connect.join(60 * 10)
        socket_connect_msg = socket_connect.get_result()
        logger.info('socket_connect_msg:' + str(socket_connect_msg))
        self.assertIn(Constant.FAILED_CONNECT_DB, socket_connect_msg)

        logger.info("-----------------------reconnect pid-------------------------------")
        msg = common.kill_pid(self.dbPrimaryRootNode, '18')
        self.assertEqual(msg, '')
        time.sleep(60)

        logger.info("----------------------connect opengauss----------------------")
        no_socket_connect_msg = self.primary_sh.nosocketConnect()
        logger.info(no_socket_connect_msg)
        self.assertEqual(no_socket_connect_msg, '')

        socket_connect_msg = self.primary_sh.socket_connect(file_path)
        logger.info(socket_connect_msg)
        self.assertIn(Constant.FAILED_CONNECT_DB, socket_connect_msg)

        logger.info("---------------------start TPCC----------------------")
        tpcc_result = common.startTPCC(self.dbPrimaryRootNode, self.TPCC_PATH)
        logger.info('-------------' + tpcc_result + '-----------------------')
        logger.info(tpcc_result)
        self.assertTrue(tpcc_result.find(self.TPCC_SUCCESS_MSG) > -1)

        logger.info("------------------------recover socket file------------------")
        recover_cmd = f'mv {self.file_name_bak} {self.file_name}'
        logger.info(recover_cmd)
        self.dbPrimaryUserNode.sh(recover_cmd)

        logger.info("----------------------connect opengauss----------------------")
        no_socket_connect_msg = self.primary_sh.nosocketConnect()
        logger.info(no_socket_connect_msg)
        self.assertEqual(no_socket_connect_msg, '')

        socket_connect_msg = self.primary_sh.socket_connect(file_path)
        logger.info(socket_connect_msg)
        logger.info(type(socket_connect_msg))
        self.assertEqual(socket_connect_msg, '')

    def tearDown(self):
        logger.info('----------------this is tearDown-----------------------')
        msg = common.kill_pid(self.dbPrimaryRootNode, '18')
        logger.info(msg)

        logger.info("------------------------recover socket file------------------")
        recover_cmd = f'mv {self.file_name_bak} {self.file_name}'
        logger.info(recover_cmd)
        self.dbPrimaryUserNode.sh(recover_cmd)

        # 校验刷脏页是否完成
        logger.info('校验刷脏页是否完成')
        dirty_page_finshed_flag = self.primary_sh.check_whether_remain_dirty_page()
        self.assertTrue(dirty_page_finshed_flag)

        # 校验备机是否完成数据同步
        logger.info('校验备机是否完成数据同步')
        flag_1 = self.standby_1_sh.check_data_consistency()
        self.assertTrue(flag_1)
        flag_2 = self.standby_2_sh.check_data_consistency()
        self.assertTrue(flag_2)
